import time, os
from lxml import etree
from appium.webdriver.common.touch_action import TouchAction


class Action():
    """
    将常用的查找控件方法、以及公共方法进行了二次封装。所有page都继承该类。
    """

    def __init__(self, driver):
        self.driver = driver

    def find_elements(self, by, locater):
        return self.driver.find_elements(by, locater)

    def find_by_id(self, locater):
        return self.driver.find_element_by_id(locater)

    def find_by_xpath(self, locater):
        return self.driver.find_element_by_xpath(locater)

    def find_by_access(self, locater):
        return self.driver.find_element_by_accessibility_id(locater)

    def press_keycode(self, code):
        self.driver.press_keycode(code)

    def keyevent(self, code):
        self.driver.keyevent(code)

    def is_exist(self, locater):
        """判断控件是否存在"""
        try:
            self.find_by_xpath(locater)
            return True
        except Exception as e:
            return False

    def hide_keyboard(self):
        """隐藏键盘"""
        self.driver.hide_keyboard()

    def swip_by_coordinates(self, begin=[400, 500], end=[400, 1000], element=None):
        """滑动屏幕。需要传入起始坐标。默认下划"""
        self.switch_context_to_native() #该方法需要在NATIVE下使用
        TouchAction(self.driver).press(el=element, x=begin[0], y=begin[1]).wait(500).move_to(x=end[0], y=end[1]).release().perform()

    def tap_by_scale(self, scale=[0.9, 0.9]):
        """根据比例 点击屏幕某位置"""
        width = self.driver.get_window_size()["width"]
        height = self.driver.get_window_size()["height"]
        x = width * scale[0]
        y = height * scale[1]
        self.driver.tap([(x, y)])

    def print_contexts(self):
        print("当前页面的context：")
        print(self.driver.current_context)
        print(self.driver.contexts)
        print(self.driver.page_source)

    def switch_context(self, switchto="NATIVE_APP"):
        """切换context到 webview、native"""
        try:
            self.driver.switch_to.context(switchto)
        except Exception as e:
            print("切换context失败！")
            contexts = self.driver.contexts
            print("所有context：" + str(contexts))
            raise e

    def switch_context_to_native(self):
        self.switch_context("NATIVE_APP")

    def switch_context_to_webview(self):
        self.switch_context("WEBVIEW_com.tencent.mm:tools")

    def wait_object(self, info, wait_time=5, step=0.5):
        """等待指定控件出现"""
        wait_time = int(wait_time)
        step = float(step)
        loop = int(wait_time/step)
        for i in range(loop):
            time.sleep(step)
            if info.find():
                break

    def switch_window(self, callback, *args, **kwargs):
        """切换窗口句柄的回调函数"""
        # 传入 函数名 以及函数的参数即可，函数名不要带括号
        handles = self.driver.window_handles
        result = None
        trytimes = 0
        for h in handles:
            self.driver.switch_to.window(h)
            try:
                result = callback(*args, **kwargs)
                print("切换窗口句柄成功！")
                break
            except Exception as e:
                trytimes += 1
                if trytimes == len(handles):
                    print("所有窗体中都执行失败！以下为异常信息：")
                    raise e
        return result

    def xpath_in_page_source(self, locater):
        """获取页面源码，然后用lxml模块过滤xpath"""
        source_code = self.driver.page_source
        elements = etree.HTML(source_code).xpath(locater)
        return elements

    def save_screenshot(self, filename):
        """截图操作"""
        project_dir = os.path.abspath('..')  # 项目目录
        dir = "result/screenshot/%s" % filename
        path = os.path.join(project_dir, dir)
        self.switch_context_to_native()
        self.driver.save_screenshot(path)


